package airwallex

import (
	"context"
	"errors"
	"fmt"
	"github.com/goccy/go-json"
	"github.com/hibiken/asynq"
	"math/rand"
	"simplifly-tech/consts"
	"simplifly-tech/payment/common"
	model2 "simplifly-tech/payment/model"
	errCode "simplifly-tech/utility/errcode"
	"simplifly-tech/utility/log"
	"simplifly-tech/utility/task"
	"slices"
	"strconv"
	"time"
)

func (airwallexService *AirwallexService) Pay(ctx context.Context, payData *model2.PayData) (*model2.PaymentResponse, error) {

	newTime := strconv.FormatInt(time.Now().Unix(), 10)
	randomInt := rand.Intn(100)
	fmt.Println("Random Int:", randomInt)

	orderID := fmt.Sprintf("order-%d%d", common.RandomInRange(1000, 9999), newTime)
	//如果需要注册用
	//agency, err := dto.GetCachedAgencyById(context.Background(), paymentData.AgencyId)
	//courID, err := airwallexService.createCustomer(agency)
	//reqData.CustomerId = courID

	//payReqDataItinerariesMap := make([]*PayReqDataItineraries, 0, len(orderDetail.Segments)*len(orderDetail.ParentOrderId)) TODO 等需要风控时候打开注释
	//价格？

	minCurrency := []string{
		"BIF", "CLP", "DJF", "GNF", "HUF", "IDR", "ISK", "JPY", "KMF", "KRW", "MGA", "PYG", "RWF", "TWD", "UGX", "VND", "VUV", "XAF", "XOF", "XPF",
	}
	minCurrencyIndex := slices.IndexFunc(minCurrency, func(s string) bool {
		return s == payData.Currency
	})

	var priceRound int32
	if minCurrencyIndex > -1 {
		priceRound = 0
	} else {
		priceRound = 2
	}

	reqData := PayReqData{
		Amount:          payData.Amount.RoundUp(priceRound),
		Currency:        payData.Currency,
		RequestId:       orderID,
		ReturnUrl:       payData.ReturnUrl,
		MerchantOrderId: orderID,
		Descriptor:      payData.Title,
		Order: &PayReqDataOrder{
			//Itineraries: payReqDataItinerariesMap,
			Products: payData.AirWallexData.PayReqDataOrderProducts.([]*PayReqDataOrderProducts),
		},
		Customer: &PayCustomer{
			Email:       payData.Email,
			PhoneNumber: payData.PhoneNumber, //.Agency.ContactInfo.ContactPhone,
			//FirstName:   flightPassengerTickets[0].GivenNames,
			LastName: payData.LastName,
		},
	}

	payResp, err := airwallexService.getResponse(SendCodePay, reqData, "POST")
	if nil != err {
		return nil, err
	}

	var respData PayRespData
	err = json.Unmarshal(payResp, &respData)
	if err != nil {
		log.Errorf("airwallex反序列化异常： %v", err)
		return nil, err
	}

	if respData.Status != "REQUIRES_CAPTURE" && respData.Status != "REQUIRES_PAYMENT_METHOD" {

		log.Errorf("(airwallexService *AirwallexService) Pay code :%s message :%s", respData.Code, respData.Message)
		return nil, errCode.NewError(nil, errors.New(respData.Message))
	}

	_, e := task.Enqueue(asynq.NewTask(string(consts.CancelAirwallexPayInfo), []byte(respData.Id)), asynq.ProcessIn(30*time.Minute)) //asynq.ProcessIn(5*time.Minute)
	if e != nil {
		log.Errorf("SyncOrderDetail  task.Enqueue(asynq.NewTask(string(consts.SyncFlightOrderUnififiNotify) err %v", e)
	}

	return &model2.PaymentResponse{
		OrderID: orderID,
		AirWallexData: model2.PayAirWallexResponse{
			AsyncPayment: true,
			PayData: model2.AirWallexPayment{
				ClientSecret: respData.ClientSecret,
				IntentId:     respData.Id,
				Currency:     respData.Currency,
			},
		},
	}, nil
}

func (airwallexService *AirwallexService) CancelPay(tx context.Context, paymentID string) error {
	reqData := AirWallexCancelPayReq{
		CancellationReason: "Order Cancel",
		RequestId:          fmt.Sprintf("%d%s", time.Now().Unix(), paymentID),
	}

	payResp, err := airwallexService.getResponse("/api/v1/pa/payment_intents/"+paymentID+"/cancel", reqData, "POST")
	if nil != err {
		return err
	}
	var respData AirWallexCancelPayRespData
	err = json.Unmarshal(payResp, &respData)
	if err != nil {
		log.Errorf("airwallex CancelPay反序列化异常： %v", err)
		return err
	}
	if respData.Status == "CANCELLED" {
		return nil
	}
	log.Errorf("airwallexService CancelPay err %s", string(payResp))
	return errCode.NewError(nil, errors.New(respData.Message))
}
